module FRM_FAS_CHECK(
   RESET,
   RCLK_155M,

   FAS_MATCH_DATA,
   FAS_MATCH_HIT,

   FAS_LOF,
   FAS_OOF
   );

input              RESET;
input              RCLK_155M;

output reg         FAS_LOF;
output reg         FAS_OOF;
input[63:0]        FAS_MATCH_DATA;
input              FAS_MATCH_HIT;


reg[2:0]           FCNT_CNT8;
reg[8:0]           FCNT_CNT270;
reg[3:0]           FCNT_CNT9;

wire               FCHK_RESTART;
reg                FCHK_FAS_ERR;
reg[4:0]           FCHK_LOF_CNT24;


// frame counter generate
always @(posedge RESET or posedge RCLK_155M) begin : COUNTER_64BYTES
   if ( RESET==1'b1 )
      FCNT_CNT8[2:0]           <= 3'd0;
   else begin
      if ( FAS_MATCH_HIT==1'b1 && FCHK_RESTART==1'b1)
          FCNT_CNT8[2:0]       <= 3'd0;
      else
          FCNT_CNT8[2:0]       <= FCNT_CNT8[2:0] +3'd1;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin : COUNTER_ROW_270
   if ( RESET==1'b1 )
      FCNT_CNT270[8:0]         <= 9'd0;
   else begin
      if ( FAS_MATCH_HIT==1'b1 && FCHK_RESTART==1'b1) begin  // FAS_MATCH_HIT indicate the last "F6" of FAS
         FCNT_CNT270[8:0]      <= 9'd3;
      end
      else if ( FCNT_CNT8[2:0]==3'b111 ) begin
         if ( FCNT_CNT270[8:0] ==9'd269 )
            FCNT_CNT270[8:0]   <= 9'd0;
         else
            FCNT_CNT270[8:0]   <= FCNT_CNT270[8:0] +9'd1;
      end
   end
end
always @(posedge RESET or posedge RCLK_155M) begin : COUNTER_COL_9
   if ( RESET==1'b1 )
      FCNT_CNT9[3:0]           <= 4'd0;
   else begin
      if ( FAS_MATCH_HIT==1'b1 && FCHK_RESTART==1'b1) begin
         FCNT_CNT9[3:0]        <= 4'd0;
      end
      else if ( FCNT_CNT8[2:0]==3'b111 && FCNT_CNT270[8:0] ==9'd269 ) begin
         if ( FCNT_CNT9[3:0]==4'd8 )
            FCNT_CNT9[3:0]     <= 4'd0;
         else
            FCNT_CNT9[3:0]     <= FCNT_CNT9[3:0] +4'd1;
      end
   end
end


// generate FAS check reslt, count the frames without correct FAS
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      FCHK_FAS_ERR             <= 1'b0;
   else begin
      if ( FCNT_CNT8[2:0]==3'd0 && ( FCNT_CNT270[8:0] ==9'd0 || FCNT_CNT270[8:0] ==9'd1 || FCNT_CNT270[8:0] ==9'd2 ) ) begin
         if ( FAS_MATCH_DATA[63:0]!=64'hF6F6F6F6_F6F6F6F6 )
            FCHK_FAS_ERR       <= 1'b1;
      end
      else if ( FCNT_CNT8[2:0]==3'd0 && ( FCNT_CNT270[8:0] ==9'd3 || FCNT_CNT270[8:0] ==9'd4 || FCNT_CNT270[8:0] ==9'd5 ) ) begin
         if ( FAS_MATCH_DATA[63:0]!=64'h28282828_28282828 )
            FCHK_FAS_ERR       <= 1'b1;
      end
      else if ( FCNT_CNT8[2:0]==3'd0 && FCNT_CNT270[8:0] ==9'd8 && FCNT_CNT8[2:0]==3'd7 )
            FCHK_FAS_ERR       <= 1'b0;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      FCHK_LOF_CNT24[4:0]             <= 5'd23;
   else begin
      if ( FCHK_LOF_CNT24[4:0]>=5'd3 && FAS_MATCH_HIT==1'b1 )  // OOF or LOF condition
         FCHK_LOF_CNT24[4:0]          <= 5'd0;
      else if ( FCNT_CNT8[2:0]==3'd0 && FCNT_CNT270[8:0] ==9'd8 && FCNT_CNT8[2:0]==3'd7 ) begin
         if ( FCHK_FAS_ERR==1'b1 && FCHK_LOF_CNT24[4:0]!=5'd23 )
            FCHK_LOF_CNT24[4:0]       <= FCHK_LOF_CNT24[4:0] +5'd1;
         else
            FCHK_LOF_CNT24[4:0]       <= 5'd0;
      end
   end
end

always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      FAS_LOF                  <= 1'b1;
   else begin
      if ( FCHK_LOF_CNT24[4:0]==5'd23 ) begin
         if ( FAS_MATCH_HIT==1'b1 )
            FAS_LOF            <= 1'b0;
         else
            FAS_LOF            <= 1'b1;
      end
      else
         FAS_LOF               <= 1'b0;
   end
end
always @(posedge RESET or posedge RCLK_155M) begin
   if ( RESET==1'b1 )
      FAS_OOF                  <= 1'b1;
   else begin
      if ( FCHK_LOF_CNT24[4:0]>=5'd23 ) begin
         if ( FAS_MATCH_HIT==1'b1 )
            FAS_OOF            <= 1'b0;
         else
            FAS_OOF            <= 1'b1;
      end
      else
          FAS_OOF              <= 1'b0;
   end
end
  assign  FCHK_RESTART  =FAS_OOF;



endmodule
